package org.example.pingpong.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.example.pingpong.domain.dto.ScoreFormDTO;
import org.example.pingpong.domain.po.Score;
import org.example.pingpong.domain.po.User;
import org.example.pingpong.domain.vo.Result;
import org.example.pingpong.service.ScoreService;
import org.example.pingpong.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;

/**
 * 分数管理接口
 */
@Api(tags = "05.分数管理接口")
@RestController
@RequestMapping("/score")
public class ScoreController {

    @Autowired
    private ScoreService scoreService;

    @Autowired
    private UserService userService;

    /**
     * 新增分数
     *
     * @param score 新增的分数信息
     * @return 返回操作结果
     */
    @ApiOperation("成绩添加接口")
    @PostMapping("/add")
    public Result add(@RequestBody ScoreFormDTO score) {
        if(!scoreService.list(new LambdaQueryWrapper<Score>().eq(Score::getUserId, score.getUserId()).eq(Score::getEventId, score.getEventId())).isEmpty()) {
            return Result.fail(555, "该场此运动员已有得分");
        }

        // 新增分数时，清除 ID，以确保是新记录
        score.setId(null);

        // 将 ScoreFormDTO 转换为 Score 实体
        Score save = new Score();
        BeanUtils.copyProperties(score, save);

        //将用户rating根据得分增加。
        User u = userService.getById(score.getUserId());
        u.setRating(u.getRating() + (68 - (int) score.getScore().charAt(0)) * 10);

        userService.updateById(u);

        // 保存分数信息
        scoreService.save(save);
        return Result.success(null); // 返回成功结果
    }

    /**
     * 删除分数
     *
     * @param ID 要删除的分数 ID
     * @return 返回操作结果
     */
    @ApiOperation("成绩删除接口")
    @DeleteMapping("/delete")
    public Result delete(@RequestParam @NotNull Integer ID) {

        Score score = scoreService.getById(ID);

        // 根据 ID 删除分数
        scoreService.removeById(ID);

        //将用户rating根据得分增加。
        User u = userService.getById(score.getUserId());
        u.setRating(u.getRating() - (68 - (int) score.getScore().charAt(0)) * 10);

        userService.updateById(u);

        return Result.success(null); // 返回成功结果
    }

    /**
     * 更新分数信息
     *
     * @param score 要更新的分数信息
     * @return 返回更新后的分数信息
     */
    @ApiOperation("成绩修改接口")
    @PutMapping("/edit")
    public Result edit(@RequestBody ScoreFormDTO score) {
        score.setUserId(null);
        score.setEventId(null);
        // 将更新的 ScoreFormDTO 转换为 Score 实体
        Score up = new Score();
        BeanUtils.copyProperties(score, up);

        //将用户rating根据得分修改。
        Score old = scoreService.getById(up.getId());
        User u = userService.getById(old.getUserId());
        u.setRating(u.getRating() + (old.getScore().charAt(0) - score.getScore().charAt(0)) * 10);

        userService.updateById(u);
        // 更新分数信息
        scoreService.updateById(up);
        return Result.success(scoreService.getById(score.getId())); // 返回更新后的分数信息
    }

    /**
     * 获取所有分数信息
     *
     * @param PAGE 页码
     * @param SIZE 每页条数
     * @return 返回分数列表
     */
    @ApiOperation("获取所有成绩接口")
    @GetMapping("/list")
    public Result list(@RequestParam @NotNull Integer PAGE, @RequestParam @NotNull Integer SIZE) {
        // 获取分页后的分数列表
        return Result.success(scoreService.page(new Page<>(PAGE, SIZE)).getRecords());
    }

    /**
     * 根据事件 ID 获取对应的分数列表，按分数排序
     *
     * @param PAGE 页码
     * @param SIZE 每页条数
     * @param ID   事件 ID
     * @return 返回按分数排序的分数列表
     */
    @ApiOperation("获取单个赛事相关成绩接口")
    @GetMapping("/ratebyevent")
    private Result rateByEvent(@RequestParam Integer PAGE, @RequestParam Integer SIZE, @RequestParam Integer ID) {
        // 构造查询条件，按事件 ID 和分数排序
        LambdaQueryWrapper<Score> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Score::getEventId, ID).orderByAsc(Score::getScore);

        // 获取分页后的分数列表
        Page<Score> page = scoreService.page(new Page<>(PAGE, SIZE), wrapper);
        return Result.success(page.getRecords()); // 返回分数列表
    }

}
